import Base3d from "../base/Base3d";
import * as THREE from "three";
import beisaier from "../base/geometryFactory/beisaier";
import LocationHelper from "../tool/LocationHelper";
import {bd09towgs84, bd09towgs84arr} from "../tool/LngLatHelper";
import config from "../config/config";
import wsEvents from "../../components/wsEvents";
import appGroup from "../main/appGroup";
export default class flyLine extends Base3d{
  init() {
    super.init();
    this.R=config.getConfigByKey("outWorldR")
    this.lines=[];
    this.lineMaterial=[];
    this.lineGroup=new THREE.Group()
    this.lineGroup.name="bersaierGroup"
    this.lightScene.add(this.lineGroup)
    //this.lineGroup.position.setZ(8);
    window.app.register("addFlyLine",(startLngLat,endLngLat)=>{
      this.createBeisaier(startLngLat,endLngLat)
    })
    window.locationConfig=[
      {
        "startPoint": bd09towgs84arr([190.535027,53.199453]),
        "endPoint":  bd09towgs84arr(["104.07274727","30.5789937"])
      }
    ]
    app.register('addFlyLine', (locationConfig)=>{
      locationConfig.forEach((item)=>{
        this.createBeisaier(item["startPoint"],item["endPoint"])
      })
    })

    app.register(wsEvents.events.ON_PUSH_TASK,(msg)=>{
      let group=this.createBeisaier(
        bd09towgs84arr([msg.source.lng,msg.source.lat]),
        bd09towgs84arr([msg.to.lng,msg.to.lat]))
      setTimeout(()=>{
        group.parent.remove(group)
      },5000)
    })
  }

  /**
   * 贝塞尔曲线计算控制点 在一个球面上计算控制点
   * @author jjawesome
   * @email 1293777844@qq.com
   * @param startLngLat
   * @param endLngLat
   */
  computeControlPoint(startLngLat,endLngLat,height){
    let startxyz=LocationHelper.lglt2xyz(startLngLat[0],startLngLat[1],this.R)
    let endxyz=LocationHelper.lglt2xyz(endLngLat[0],endLngLat[1],this.R);
    let startLineToOriginPoint = new THREE.Vector3(startxyz.x,startxyz.y,startxyz.z)
  }
  createBeisaier(startLngLat,endLngLat){
    let startxyz=LocationHelper.lglt2xyz(startLngLat[0],startLngLat[1],this.R)
    let endxyz=LocationHelper.lglt2xyz(endLngLat[0],endLngLat[1],this.R);
    let control=new THREE.Vector3((startxyz.x+endxyz.x)/2.0,(startxyz.y+endxyz.y)/2.0,(startxyz.z+endxyz.z)/2.0-this.R/4.0)
    let group=new THREE.Group();
    group.add(this.createLine(startxyz,endxyz,control,"x"))
    group.add(this.createLine(startxyz,endxyz,control,"y"))
    this.lineGroup.add(group)
    return group
  }
  createLine(startPoint,endPoint,controlPoint,model,op=0.9){
    let lineMaterial = new THREE.ShaderMaterial({
      transparent: true,
      side:THREE.DoubleSide,
      uniforms: {
        u_time: {
          'type': "f",
          'value': 0.0,
        },
        PI:{
          value:Math.PI
        },
        w:{
          value:op
        },
        startX:{
          value:0.0
        },
        uCircleColor:{
          value:new THREE.Color(0x28F29F)
        },
        uLightColor:{
          value:new THREE.Color(0x23CEFE)
        },
        uLightPercent:{
          value:0.15
        },
      },
      vertexShader: `
          varying vec2 uVu;
          varying vec3 aPosition;
          void main(){
              uVu=uv;
              aPosition=position;
              gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
          }
        `,
      fragmentShader: `
             varying vec2 uVu;
          uniform float u_time;
          uniform float PI;
          uniform float startX;
          varying vec3 aPosition;
          uniform sampler2D uTexture;
          uniform vec3 uCircleColor;
          uniform vec3 uLightColor;
          uniform float uLightPercent;
          uniform float w;
          uniform sampler2D uLightTexture;
          float remain(float x,float num){
                return x-floor(x/num)*num;
          }
          //是否是奇数
          float isSingleNum(float x){
                return ceil(remain(x,2.0));
          }
          float circleMax(float min){
                return step(min,distance(uVu.xy,vec2(0.5,0.5)));
          }
          float circleMin(float max){
                return step(distance(uVu.xy,vec2(0.5,0.5)),max);
          }
          float hasColor(vec3 color){
                return ceil((color.x+color.y+color.z)/10.0);
          }
          float singleIncrease(float x){
              x=remain(x,PI*2.0);
              float sinData=1.0-ceil(step(PI/2.0,remain(x,PI)));
              float cosData=isSingleNum(floor(x/(PI/2.0)));
              return cosData*abs(cos(x))+sinData*abs(sin(x));
          }
          float singleSub(float x){
              x=remain(x,PI*2.0);
              float sinData=1.0-ceil(step(PI/2.0,remain(x,PI)));
              float cosData=isSingleNum(floor(x/(PI/2.0)));
              return (1.0-cosData)*abs(cos(x))+(1.0-sinData)*abs(sin(x));
          }
          //将某个数分散到固定的区间
          float dispersed(float num,float count){
                float avg=num/count;
                return floor(num/avg);
          }
          //计算高亮系数
          float ellipseRatio(float x,float y,float max,float min){
                float result=pow(uVu.x-x,2.0)/pow(max,2.0)+pow(uVu.y-y,2.0)/pow(min,2.0);
                return step(result,1.0);
          }
          vec4 getLightColor(){
               vec2 uVu2=vec2(1.0-uVu.x,1.0-uVu.y);
               vec4 lightColor=step(singleIncrease(u_time),uVu2.x)*step(uVu2.x,singleIncrease(u_time)+uLightPercent)*vec4(uLightColor,1.0);
               float middleX=singleIncrease(u_time)+uLightPercent/2.0;
               lightColor=lightColor*(1.0-abs(middleX-uVu2.x)*5.0);
               vec4 HightColor=vec4(1.0,1.0,1.0,1.0)*ellipseRatio(1.0-middleX,0.5,0.006,0.3);
               //HightColor+=(1.0-hasColor(HightColor.xyz))*(1.0-dispersed(abs(uVu2.x-middleX),100.0)/100.0);
               return (lightColor+HightColor)*3.5;
          }
          vec4 smoothColor(){
               float middleX=singleIncrease(u_time)+uLightPercent/2.0;
               return vec4(1.0,1.0,1.0,1.0)*abs(uVu.x-middleX)*0.5;
          }
          vec2 getNewUv(){
               vec2 uVu2=vec2(1.0-uVu.x,1.0-uVu.y);
               float max=singleIncrease(u_time)+uLightPercent;
               float min=singleIncrease(u_time);
               float x=uVu2.x;
               x=(x-min)*step(min,x);
               x=x*10.0;
               return vec2(x,uVu2.y);
          }
          void main(){
               vec4 lightColor=getLightColor();
               //lightColor=hasColor(lightColor.xyz)*texture2D(uLightTexture,getNewUv());
               vec4 color=texture2D(uTexture,uVu.xy)*step(distance(uVu.xy,vec2(0.5,0.5)),startX);
               color=hasColor(color.xyz)*vec4(uCircleColor,1.0)*circleMin((singleSub((u_time)/4.0)))+color;
               float op=1.0*w-abs(0.0-(uVu.x*0.4)*w);
               //op+=(dispersed(0.2,10.0)*(w))/10.0;
               vec4 baseColor=vec4(uCircleColor+vec3(1.0,1.0,1.0)*uVu.x*w*0.6,op)*(1.0-hasColor(lightColor.xyz))*0.0;
               gl_FragColor = (baseColor+lightColor)*step(uVu.x,startX);
          }
        `,
    });
    if(model=="x"){
      lineMaterial.polygonOffset=true;
      lineMaterial.polygonOffsetFactor=-5.0;
      lineMaterial.polygonOffsetpolygonOffsetUnits=2.0;
    }else {
      lineMaterial.polygonOffset=true;
      lineMaterial.polygonOffsetFactor=-4.0;
      lineMaterial.polygonOffsetpolygonOffsetUnits=1.0;
    }
    let line=new beisaier().getGeometry(startPoint,endPoint,controlPoint,0.5,30,model);
    let mesh = new THREE.Mesh(line,lineMaterial);
    mesh.name="flyLine"
    let x=Math.abs(startPoint.x-endPoint.x);
    let y=Math.abs(startPoint.y-endPoint.y);
    this.lineMaterial.push(lineMaterial);

    return mesh;
  }
  render() {
    this.lineMaterial.forEach((item)=>{
      item.uniforms.u_time.value+=0.005;
      item.uniforms.startX.value+=0.012;
    })

    super.render();
  }
}
